#include <iostream>
#include <assert.h>
#include <format>
namespace my_forward_lists
{
    template <typename T>
    class my_forward_list{
    private:
        struct Node
        {
            T data;
            Node* next;
            Node(const T& value):data(value),next(nullptr){}
        };
        Node* head;
        size_t m_size;      
    public:
        my_forward_list():head(nullptr),m_size(0){}
        
        ~my_forward_list(){
            clear();
        }
        
        void push_back(const T& val){
            Node* newNode = new Node(val);
            
            if (head == nullptr) {
                // List is empty, new node becomes head
                head = newNode;
            } else {
                // Find the last node
                Node* temp = head;
                while(temp->next != nullptr) {
                    temp = temp->next;
                }
                temp->next = newNode;
            }
            m_size++;
        }

        void push_front(const T& val){
            Node* newNode = new Node(val);
            newNode->next = head;  // New node points to current head
            head = newNode;        // New node becomes the new head
            m_size++;
        }
        
        T& front() const {
            assert(head != nullptr);  // Check if list is not empty
            return head->data;        // Return data of head node
        }
        
        size_t size() const {  // Should be const
            return m_size;
        }

        void clear(){
            Node* current = head;
            while(current != nullptr) {
                Node* next = current->next;
                delete current;
                current = next;
            }
            head = nullptr;
            m_size = 0;
        }

        void display(){
            assert(head!=nullptr);
            std::cout<<"\n=====Content=====\n";
            Node* temp = head;
            while(temp!=nullptr){
                std::cout<<std::format("{} ",temp->data);
                temp = temp->next;
            }
        }
        
        // Additional useful methods:
        bool empty() const {
            return head == nullptr;
        }
        
        // Copy constructor (rule of three)
        my_forward_list(const my_forward_list& other) : head(nullptr), m_size(0) {
            Node* current = other.head;
            while (current != nullptr) {
                push_back(current->data);
                current = current->next;
            }
        }
        
        // Assignment operator (rule of three)
        my_forward_list& operator=(const my_forward_list& other) {
            if (this != &other) {
                clear();
                Node* current = other.head;
                while (current != nullptr) {
                    push_back(current->data);
                    current = current->next;
                }
            }
            return *this;
        }
    };
} // namespace my_forward_lists